package run;

import java.awt.Rectangle;

import hypermedia.video.Blob;
import hypermedia.video.OpenCV;
import processing.core.PApplet;
import processing.core.PImage;
import processing.core.PVector;

public class MarioGameEnv {

	int w, h;
	PApplet parent;
	int[] pix;
	public CVSuperImposition cvs;
	Blob[] blobs;
	
	public MarioGameEnv(OpenCV opencv, PApplet applet) {
		//TODO do better than thresholding; do some smarter edge detection

		cvs = new CVSuperImposition(opencv, applet);
		this.blobs = cvs.analyze();
		
//		renderBlobs(blobs, applet);

		PImage pImage = opencv.image();
		pImage.loadPixels();
		pix = pImage.pixels;
		w = pImage.width;
		h = pImage.height;
		
		parent = applet;
	}
	
	public void renderBlobs(PApplet p) {
		renderBlobs(blobs, p);
	}
	
	private void renderBlobs(Blob[] blobs, PApplet p) {
		// TODO Auto-generated method stub
		// CLASSIFY THE BLOB; if it's very square (width and height deviate by less than 10%)
	    // consider it a pipe!!!

		//	    if (display_thresh) {
//		p.image(opencv.image(),0,0); //TODO danger; crashasble.
	//}

	    for (Blob b : blobs) {
	    	Rectangle r = b.rectangle;
	    	if (p.abs(r.width - r.height)/(r.width) < 0.1F)
	    	{
	    		System.out.println("square blob at " + r.x + ", " + r.y);
	    		
	    		p.fill(0,0,90,90);
	    		p.rect(r.x, r.y, r.width, r.height);
	    	}
	    }		
	}

	// scan the range... return true or false
	public boolean collidesWithObj(PVector a) {
		if (! outOfBounds(a))
			return pixelOccupied(a);
		else return false;
	}
	
	public boolean pixelOccupied(PVector pt) {
		if (outOfBounds(pt))
			return false;
			
		if ( getPixel(pt) == parent.color(0,0,0) )
			return true;
		else return false;
	}
	
	private int getPixel(PVector v) {
		return pix[ (int)  ((w * v.y) + v.x) ];
	}

	// scan the range... return the length of the range
	public PVector min_intersection(PVector a, PVector b) {
		PVector diff = PVector.sub(b, a);
		
		int steps = (int) diff.mag();
		PVector step = PVector.div(diff, diff.mag());
		
		for (int i = 0; i <= steps; i++) {
			PVector pixelLoc = PVector.add(a, PVector.mult(step, i));
			if (pixelOccupied( pixelLoc)) {
				return PVector.mult(diff, i);
			}
		}
		
		return diff;
	}

	public boolean outOfBounds(PVector p) {
		return (p.x < 0 || p.x >= w || p.y < 0 || p.y >= h);
	}

}
